Micron Document
πŸŽ–οΈGitΠ―Ρ€Π°πŸŽ–οΈ

Node / meshtastic / Meshtastic-Android / files / docs / kmp-status.md

Displaying Rendered β€’ View raw β€’ Download

docs/kmp-status.md f07624be882e679affc02931dc75e8cb1594de18 (f07624be) Text, 13.78 KB

KMP Migration Status

β”‚ Last updated: 2026-03-31

Single source of truth for Kotlin Multiplatform migration progress. For the forward-looking roadmap, see roadmap.md. For completed decision records, see decisions/.

Summary

Meshtastic-Android has completed its Android-first structural KMP migration across core logic and feature modules, with full JVM cross-compilation validated in CI. The desktop target has a working Navigation 3 shell, TCP transport with full mesh handshake, and multiple features wired with real screens.

Modules that share JVM-specific code between Android and desktop now standardize on the T383838meshtastic.kmp.jvm.android convention plugin, which creates T383838jvmAndroidMain via Kotlin's hierarchy template API instead of manual T383838dependsOn(...) source-set wiring.

Module Inventory

Core Modules (21 total)

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Module β”‚ KMP? β”‚ JVM target? β”‚ Notes β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ T383838core:proto β”‚ βœ… β”‚ βœ… β”‚ Protobuf definitions β”‚
β”‚ T383838core:common β”‚ βœ… β”‚ βœ… β”‚ Utilities, T383838jvmAndroidMain source set β”‚
β”‚ T383838core:model β”‚ βœ… β”‚ βœ… β”‚ Domain models, T383838jvmAndroidMain source set β”‚
β”‚ T383838core:repository β”‚ βœ… β”‚ βœ… β”‚ Domain interfaces β”‚
β”‚ T383838core:di β”‚ βœ… β”‚ βœ… β”‚ Dispatchers, qualifiers β”‚
β”‚ T383838core:navigation β”‚ βœ… β”‚ βœ… β”‚ Shared Navigation 3 routes β”‚
β”‚ T383838core:resources β”‚ βœ… β”‚ βœ… β”‚ Compose Multiplatform resources β”‚
β”‚ T383838core:datastore β”‚ βœ… β”‚ βœ… β”‚ Multiplatform DataStore β”‚
β”‚ T383838core:database β”‚ βœ… β”‚ βœ… β”‚ Room KMP β”‚
β”‚ T383838core:domain β”‚ βœ… β”‚ βœ… β”‚ UseCases β”‚
β”‚ T383838core:prefs β”‚ βœ… β”‚ βœ… β”‚ Preferences layer β”‚
β”‚ T383838core:network β”‚ βœ… β”‚ βœ… β”‚ Ktor, T383838StreamFrameCodec, T383838TcpTransport, T383838SerialTransport, T383838B… β”‚
β”‚ T383838core:data β”‚ βœ… β”‚ βœ… β”‚ Data orchestration β”‚
β”‚ T383838core:ble β”‚ βœ… β”‚ βœ… β”‚ Kable multiplatform BLE abstractions in commonMain β”‚
β”‚ T383838core:nfc β”‚ βœ… β”‚ βœ… β”‚ NFC contract in commonMain; hardware in androidMain β”‚
β”‚ T383838core:service β”‚ βœ… β”‚ βœ… β”‚ Service layer; Android bindings in androidMain β”‚
β”‚ T383838core:ui β”‚ βœ… β”‚ βœ… β”‚ Shared Compose UI, pure KMP QR generator, T383838jvmAndroidMain… β”‚
β”‚ T383838core:testing β”‚ βœ… β”‚ βœ… β”‚ Shared test doubles, fakes, and utilities for T383838commonTest β”‚
β”‚ T383838core:takserver β”‚ βœ… β”‚ βœ… β”‚ TAK/ATAK integration, Fountain codec β”‚
β”‚ T383838core:api β”‚ ❌ β”‚ β€” β”‚ Android-only (AIDL). Intentional. β”‚
β”‚ T383838core:barcode β”‚ ❌ β”‚ β€” β”‚ Android-only (CameraX). Flavor split minimised to decode… β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

19/21 core modules are KMP with JVM targets. The 2 Android-only modules are intentionally platform-specific, with shared contracts already abstracted into T383838core:ui/commonMain.

Feature Modules (9 total β€” 9 KMP with JVM, 1 Android-only widget)

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Module β”‚ UI in commonMain? β”‚ Desktop wired? β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ T383838feature:settings β”‚ βœ… β”‚ βœ… ~35 real screens; fully shared T383838settingsGraph an… β”‚
β”‚ T383838feature:node β”‚ βœ… β”‚ βœ… Adaptive list-detail; fully shared T383838nodesGraph, T383838… β”‚
β”‚ T383838feature:messaging β”‚ βœ… β”‚ βœ… Adaptive contacts + messages; fully shared T383838cont… β”‚
β”‚ T383838feature:connections β”‚ βœ… β”‚ βœ… Shared T383838ConnectionsScreen with dynamic transport… β”‚
β”‚ T383838feature:intro β”‚ β€” β”‚ β€” β”‚
β”‚ T383838feature:map β”‚ β€” β”‚ Placeholder; shared T383838NodeMapViewModel and T383838BaseMapVi… β”‚
β”‚ T383838feature:firmware β”‚ βœ… β”‚ βœ… Fully KMP: Unified OTA, native Secure DFU, USB/… β”‚
β”‚ T383838feature:wifi-provision β”‚ βœ… β”‚ βœ… KMP WiFi provisioning via BLE (Nymea protocol);… β”‚
β”‚ T383838feature:widget β”‚ ❌ β”‚ β€” β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Desktop Module

Working Compose Desktop application with:
β€’ Navigation 3 shell (T383838NavigationRail + T383838NavDisplay) using shared routes
β€’ Full Koin DI graph (stubs + real implementations)
β€’ TCP, Serial/USB, and BLE transports with auto-reconnect and full T383838want_config handshake
β€’ Adaptive list-detail screens for nodes and contacts
β€’ Dynamic Connections screen with automatic discovery of platform-supported transports (TCP, Serial/USB, BLE)
β€’ Desktop language picker backed by T383838UiPreferencesDataSource.locale, with immediate Compose Multiplatform resource updates
β€’ Navigation-preserving locale switching via T383838Main.kt T383838staticCompositionLocalOf recomposition instead of recreating the Nav3 backstack
β€’ Node detail metrics screens (Device, Environment, Signal, Power, Pax) wired with shared KMP + Vico charts
β€’ Feature-driven Architecture: Desktop navigation completely relies on feature modules via T383838commonMain exported graphs (T383838settingsGraph, T383838nodesGraph, T383838contactsGraph, etc.), reducing the desktop module to a simple host shell.
β€’ Native notifications and system tray icon wired via T383838DesktopNotificationManager
β€’ Native release pipeline generating T383838.dmg (macOS), T383838.msi (Windows), and T383838.deb (Linux) installers in CI

Scorecard

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Area β”‚ Score β”‚ Notes β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Shared business/data logic β”‚ 9/10 β”‚ All core layers shared; RadioTransport interface unified β”‚
β”‚ Shared feature/UI logic β”‚ 9/10 β”‚ 9 KMP feature modules; firmware fully migrated; wifi-provi… β”‚
β”‚ Android decoupling β”‚ 9/10 β”‚ No known T383838java.* calls in T383838commonMain; app module extraction… β”‚
β”‚ Multi-target readiness β”‚ 9/10 β”‚ Full JVM; release-ready desktop; iOS simulator builds comp… β”‚
β”‚ CI confidence β”‚ 9/10 β”‚ 26 modules validated (including feature:wifi-provision); n… β”‚
β”‚ DI portability β”‚ 8/10 β”‚ Koin annotations in commonMain; supportedDeviceTypes injec… β”‚
β”‚ Test maturity β”‚ 9/10 β”‚ Mokkery, Turbine, and Kotest integrated; property-based te… β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

β”‚ See
β”‚ for the full gap analysis.

Completion Estimates

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Lens β”‚ % β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Android-first structural KMP β”‚ ~100% β”‚
β”‚ Shared business logic β”‚ ~98% β”‚
β”‚ Shared feature/UI β”‚ ~92% β”‚
β”‚ True multi-target readiness β”‚ ~85% β”‚
β”‚ "Add iOS without surprises" β”‚ ~100% β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”˜

Proposed Next Steps for KMP Migration

Based on the latest codebase investigation, the following steps are proposed to complete the multi-target and iOS-readiness migrations:

1. Wire Desktop Features: Complete desktop UI wiring for T383838feature:intro and implement a shared fallback for T383838feature:map (which is currently a placeholder on desktop).
2. Flesh out iOS Actuals: Complete the actual implementations for iOS UI stubs (e.g., T383838AboutLibrariesLoader, T383838rememberOpenMap, T383838SettingsMainScreen) that were recently added to unblock iOS compilation.
3. Boot iOS Target: Set up an initial skeleton Xcode project to start running the now-compiling T383838iosSimulatorArm64 / T383838iosArm64 binaries on a real simulator/device.

Key Architecture Decisions

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Decision β”‚ Status β”‚ Details β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Navigation 3 parity model (shared T383838TopLevelDestination + platform adapters) β”‚ βœ… Done β”‚ See de: serializer registration validation and platform exception tracking.

App Module Thinning Status

All major ViewModels have now been extracted to T383838commonMain and no longer rely on Android-specific subclasses. Platform-specific dependencies (like T383838android.net.Uri or Location permissions) have been successfully isolated behind injected T383838core:repository interfaces (e.g., T383838FileService, T383838LocationService).

The extraction of all feature-specific navigation graphs, background services, and widgets out of T383838:app is complete. The T383838:app module now only serves as the root DI assembler and NavHost container.

Extracted to shared T383838commonMain (no longer app-only):
β€’ T383838SettingsViewModel β†’ T383838feature:settings/commonMain
β€’ T383838RadioConfigViewModel β†’ T383838feature:settings/commonMain
β€’ T383838DebugViewModel β†’ T383838feature:settings/commonMain
β€’ T383838MetricsViewModel β†’ T383838feature:node/commonMain
β€’ T383838UIViewModel β†’ T383838core:ui/commonMain
β€’ T383838ChannelViewModel β†’ T383838feature:settings/commonMain
β€’ T383838NodeMapViewModel β†’ T383838feature:map/commonMain (Shared logic for node-specific maps)
β€’ T383838BaseMapViewModel β†’ T383838feature:map/commonMain (Core contract for all maps)

Extracted to core KMP modules:
β€’ Android Services, WorkManager Workers, and BroadcastReceivers β†’ T383838core:service/androidMain
β€’ USB/Serial radio connections β†’ T383838core:network/androidMain
β€’ TCP radio connections, BLE radio connections (T383838BleRadioInterface), and mDNS/NSD Service Discovery β†’ T383838core:network/commonMain (with Android T383838NsdManager and Desktop T383838JmDNS implementations)

Remaining to be extracted from T383838:app or unified in T383838commonMain:
β€’ T383838MapViewModel (Unify Google/F-Droid flavors into a single T383838commonMain class consuming a T383838MapConfigProvider interface)

Prerelease Dependencies


β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Dependency β”‚ Version β”‚ Why β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Compose Multiplatform β”‚ T3838381.11.0-beta01 β”‚ Required for JetBrains Adaptive T3838381.3.0-alpha… β”‚
β”‚ Compose Multiplatform Material 3 β”‚ T3838381.11.0-alpha05 β”‚ Material 3 components including T383838NavigationS… β”‚
β”‚ Koin β”‚ T3838384.2.0 β”‚ Nav3 + K2 compiler plugin support β”‚
β”‚ JetBrains Lifecycle β”‚ T3838382.11.0-alpha02 β”‚ Multiplatform ViewModel/lifecycle; includes… β”‚
β”‚ JetBrains Navigation 3 β”‚ T3838381.1.0-beta01 β”‚ Multiplatform navigation with Scene archite… β”‚
β”‚ JetBrains Navigation Event β”‚ T3838381.1.0-alpha01 β”‚ KMP T383838NavigationBackHandler for predictive ba… β”‚
β”‚ JetBrains Material 3 Adaptive β”‚ T3838381.3.0-alpha06 β”‚ T383838ListDetailPaneScaffold, T383838ThreePaneScaffold, … β”‚
β”‚ Kable BLE β”‚ T3838380.42.0 β”‚ Provides fully multiplatform BLE support β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Policy: Stable by default. RC when it unlocks KMP functionality. Alpha only behind hard abstraction seams. Do not downgrade CMP or Koin β€” they enable critical KMP features.

β”‚ See
β”‚ for the full Navigation 3 API surface audit and Scene architecture adoption plan.

References

β€’ Roadmap: docs/roadmap.md
β€’ Agent guide: AGENTS.md
β€’ Playbooks: docs/agent-playbooks/
β€’ Decision records: docs/decisions/

Served by rngit 1.5.0 - Generated in 0.14s